package com.smartwrite.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.smartwrite.entity.TaskInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * 任务进度监控服务
 * 负责监控任务执行进度并通过WebSocket发送更新
 * 这个Java实现包括以下主要功能：
 *
 * 1. 实时监控任务进度 - 通过监控 nodes.json 文件的变化来跟踪任务状态
 * 2. WebSocket通信 - 使用Spring的WebSocket支持发送实时更新给前端
 * 3. 数据转换 - 将内部节点数据转换为适合前端显示的格式
 * 4. 错误处理 - 包含完整的异常处理机制
 * 5. 异步执行 - 在后台线程中运行，不阻塞主线程
 */
@Service
public class TaskProgressMonitorService {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    
    @Autowired
    private TaskStorageService taskStorageService;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
    private final Map<String, ScheduledFuture<?>> monitoringTasks = new ConcurrentHashMap<>();
    private final Map<String, Long> lastModifiedTimes = new ConcurrentHashMap<>();
    
    /**
     * 开始监控任务进度
     */
    public void startMonitoring(String taskId, String recordsDir) {
        // 如果已经在监控，先停止
        stopMonitoring(taskId);
        
        System.out.println("开始监控任务进度: " + taskId);
        System.out.println("监控目录: " + recordsDir);
        
        // 发送初始任务图
        sendInitialTaskGraph(taskId);
        
        // 启动定期监控
        ScheduledFuture<?> future = scheduler.scheduleWithFixedDelay(
            () -> monitorTaskProgress(taskId, recordsDir),
            1, // 初始延迟1秒
            2, // 每2秒检查一次
            TimeUnit.SECONDS
        );
        
        monitoringTasks.put(taskId, future);
    }
    
    /**
     * 停止监控任务进度
     */
    public void stopMonitoring(String taskId) {
        ScheduledFuture<?> future = monitoringTasks.remove(taskId);
        if (future != null) {
            future.cancel(true);
            System.out.println("停止监控任务进度: " + taskId);
        }
        lastModifiedTimes.remove(taskId);
    }
    
    /**
     * 发送初始任务图
     */
    private void sendInitialTaskGraph(String taskId) {
        Map<String, Object> taskGraph = new HashMap<>();
        taskGraph.put("id", "0");
        taskGraph.put("goal", "正在初始化任务...");
        taskGraph.put("task_type", "think");
        taskGraph.put("status", "DOING");
        taskGraph.put("sub_tasks", new Object[0]);
        
        Map<String, Object> message = new HashMap<>();
        message.put("taskId", taskId);
        message.put("taskGraph", taskGraph);
        
        System.out.println("发送初始任务更新: " + taskId);
        messagingTemplate.convertAndSend("/topic/task-updates", message);
    }
    
    /**
     * 监控任务进度
     */
    private void monitorTaskProgress(String taskId, String recordsDir) {
        try {
            // 检查任务是否仍在运行
            TaskInfo taskInfo = taskStorageService.getTask(taskId);
            if (taskInfo == null || taskInfo.isCompleted()) {
                stopMonitoring(taskId);
                return;
            }
            
            Path nodesFile = Paths.get(recordsDir, "nodes.json");
            
            if (Files.exists(nodesFile)) {
                long currentModified = Files.getLastModifiedTime(nodesFile).toMillis();
                Long lastModified = lastModifiedTimes.get(taskId);
                
                if (lastModified == null || currentModified > lastModified) {
                    lastModifiedTimes.put(taskId, currentModified);
                    System.out.println("检测到nodes.json文件变化，读取文件");
                    
                    try {
                        String content = Files.readString(nodesFile);
                        Map<String, Object> nodesData = objectMapper.readValue(content, Map.class);
                        
                        // 转换数据格式
                        Map<String, Object> transformedGraph = transformNodeToGraph(nodesData, true);
                        
                        // 发送更新
                        Map<String, Object> message = new HashMap<>();
                        message.put("taskId", taskId);
                        message.put("taskGraph", transformedGraph);
                        
                        System.out.println("发送任务更新，子任务数量: " + 
                            ((Object[]) transformedGraph.getOrDefault("sub_tasks", new Object[0])).length);
                        
                        messagingTemplate.convertAndSend("/topic/task-updates", message);
                        
                    } catch (Exception e) {
                        System.err.println("解析nodes.json文件失败: " + e.getMessage());
                    }
                }
            }
            
        } catch (Exception e) {
            System.err.println("监控任务进度时发生错误 [" + taskId + "]: " + e.getMessage());
        }
    }
    
    /**
     * 转换节点数据为前端图形格式
     */
    private Map<String, Object> transformNodeToGraph(Map<String, Object> nodeData, boolean isRoot) {
        Map<String, Object> graph = new HashMap<>();
        
        // 基本信息
        graph.put("id", nodeData.getOrDefault("id", "0"));
        graph.put("goal", nodeData.getOrDefault("goal", "未知任务"));
        graph.put("task_type", nodeData.getOrDefault("task_type", "think"));
        graph.put("status", nodeData.getOrDefault("status", "DOING"));
        
        // 处理动作信息
        if (nodeData.containsKey("actions") && nodeData.get("actions") instanceof Map) {
            Map<String, Object> actions = (Map<String, Object>) nodeData.get("actions");
            if (!actions.isEmpty()) {
                // 获取最新的动作
                Object latestAction = actions.values().iterator().next();
                graph.put("latest_action", latestAction);
            }
        }
        
        // 处理子任务
        if (nodeData.containsKey("children") && nodeData.get("children") instanceof Map) {
            Map<String, Object> children = (Map<String, Object>) nodeData.get("children");
            Object[] subTasks = children.values().stream()
                .map(child -> transformNodeToGraph((Map<String, Object>) child, false))
                .toArray();
            graph.put("sub_tasks", subTasks);
        } else {
            graph.put("sub_tasks", new Object[0]);
        }
        
        return graph;
    }
}